<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <script>
        // 实现一个mycall方法

        // function fn(){
        //     console.log("fn",this);
        // }
        // var obj = {name:"hello"};
        // fn.call(obj);

        // 1. fn调用的时候  让fn的this指向 obj；
        // 函数里的this 指向一个对象；
        // var myobj = {
        //     name:"hello",
        //     fn:function(){
        //         console.log(this);
        //     }
        // }
        // myobj.fn();  // fn函数里的this 指向 ？


        //2. 直接写mycall函数 
        // function mycall(fn,obj){
        //     obj = obj || window;  // 如果传入的是 null 或者是undefined 那么 obj就是window
        //     obj = Object(obj);                  // 如果传入的是简单数据类型 那么把简单数据类型变成包装对象
        //     obj.fn = fn;  // 把函数加入到obj对象里
        //     obj.fn();  // 通过obj对象调用 fn函数
        //     delete obj.fn; // 调用完毕之后 删除fn函数；
        // }

        // mycall(fn,"fdasfdsa");  // 改变fn里的this指向；

        
        // 3.把mycall函数 挂载在所有函数的原型上方便调用；
        Function.prototype.mycall = function (obj, ...arg) {
            obj = obj || window;  // 如果传入的是 null 或者是undefined 那么 obj就是window
            obj = Object(obj);                  // 如果传入的是简单数据类型 那么把简单数据类型变成包装对象
            obj.fn = this;  // 把函数加入到obj对象里
            var res = obj.fn(...arg);  // 通过obj对象调用 fn函数
            delete obj.fn; // 调用完毕之后 删除fn函数；
            return res; // 把原来函数的返还值在返还出去；
        }

        // var fn = function(){}

        function fn(a, b, c) {
            console.log("fn", this, a, b, c);
            return "你好"
        }
        var res = fn.mycall({ myname: "hello" }, 1, 2, 3);
        // var res = fn(1,2,3);
        // var res = fn.call({myname:"hello"},1,2);

        console.log(res);



    </script>
</body>

</html>